package com.blic.utils;

import java.lang.reflect.Field;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

/**
 * 获取查询Example工具类
 * 
 * @author douglas
 *
 */
public class ExampleUtil {

	/** 日志类 */
	protected static Logger logger = LoggerFactory.getLogger(ExampleUtil.class);

	/**
	 * 根据类类型以及对象返回组装的example，参数之间and连接
	 * 
	 * @param <T>
	 * 
	 * @param type
	 *            类类型
	 * @param obj
	 *            对象
	 * @return
	 * @throws Exception
	 */
	public static <T> Example getExampleUseAnd(Class<?> type, T obj) throws Exception {
		try {
			// 类类型与对象的类类型比较
			if (type != obj.getClass()) {
				throw new Exception("根据类类型以及对象返回组装的example，参数之间and连接error:传入的类类型与对象的类型性不一致");
			}
			// 查询example
			Example example = new Example(obj.getClass());
			Criteria criteria = example.createCriteria();
			// 获取properties
			Field[] fields = type.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				if (!StringUtils.isEmpty(field.get(obj)) && !("serialVersionUID".equals(field.getName()))) {
					criteria.andEqualTo(field.getName(), field.get(obj));
				}
			}
			return example;
		} catch (Exception e) {
			logger.error("根据类类型以及对象返回组装的example，参数之间and连接error:" + e.getMessage());
			throw e;
		}
	}

	/**
	 * 根据类类型以及对象返回组装的example，参数之间or连接
	 * 
	 * @param <T>
	 * 
	 * @param type
	 *            类类型
	 * @param obj
	 *            对象
	 * @return
	 * @throws Exception
	 */
	public static <T> Example getExampleUseOr(Class<?> type, T obj) throws Exception {
		try {
			// 类类型与对象的类类型比较
			if (type != obj.getClass()) {
				throw new Exception("根据类类型以及对象返回组装的example，参数之间or连接error:传入的类类型与对象的类型性不一致");
			}
			// 查询example
			Example example = new Example(obj.getClass());
			// 获取properties
			Field[] fields = type.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				if (!StringUtils.isEmpty(field.get(obj)) && !("serialVersionUID".equals(field.getName()))) {
					example.or().andEqualTo(field.getName(), field.get(obj));
				}
			}
			return example;
		} catch (Exception e) {
			logger.error("根据类类型以及对象返回组装的example，参数之间or连接error:" + e.getMessage());
			throw e;
		}
	}

	/**
	 * 根据类类型以及对象返回组装的example，参数之间and连接like模糊查询
	 * 
	 * @param <T>
	 * 
	 * @param type
	 *            类类型
	 * @param obj
	 *            对象
	 * @return
	 * @throws Exception
	 */
	public static <T> Example getExampleUseAndLike(Class<?> type, T obj) throws Exception {
		try {
			// 类类型与对象的类类型比较
			if (type != obj.getClass()) {
				throw new Exception("根据类类型以及对象返回组装的example，参数之间and连接like模糊查询:传入的类类型与对象的类型性不一致");
			}
			// 查询example
			Example example = new Example(obj.getClass());
			Criteria criteria = example.createCriteria();
			// 获取properties
			Field[] fields = type.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				if (!StringUtils.isEmpty(field.get(obj)) && !("serialVersionUID".equals(field.getName()))) {
					criteria.andLike(field.getName(), "%" + field.get(obj) + "%");
				}
			}
			return example;
		} catch (Exception e) {
			logger.error("根据类类型以及对象返回组装的example，参数之间and连接like模糊查询:" + e.getMessage());
			throw e;
		}
	}

	/**
	 * 根据类类型以及对象返回组装的example，参数之间or连接Like模糊查询
	 * 
	 * @param <T>
	 * 
	 * @param type
	 *            类类型
	 * @param obj
	 *            对象
	 * @return
	 * @throws Exception
	 */
	public static <T> Example getExampleUseOrLike(Class<?> type, T obj) throws Exception {
		try {
			// 类类型与对象的类类型比较
			if (type != obj.getClass()) {
				throw new Exception("根据类类型以及对象返回组装的example，参数之间or连接Like模糊查询error:传入的类类型与对象的类型性不一致");
			}
			// 查询example
			Example example = new Example(obj.getClass());
			// 获取properties
			Field[] fields = type.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				if (!StringUtils.isEmpty(field.get(obj)) && !("serialVersionUID".equals(field.getName()))) {
					example.or().andLike(field.getName(), "%" + field.get(obj) + "%");
				}
			}
			return example;
		} catch (Exception e) {
			logger.error("根据类类型以及对象返回组装的example，参数之间or连接Like模糊查询error:" + e.getMessage());
			throw e;
		}
	}
}
